package com.h3c.web.rest;

import java.sql.SQLException;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.h3c.dal.common.TableConstant;
import com.h3c.dal.dao.CasssoDeptDAO;
import com.h3c.dal.dao.CasssoDeptUserRelationDAO;
import com.h3c.dal.dao.CasssoOrganizationUnitDAO;
import com.h3c.dal.dao.CasssoRoleDAO;
import com.h3c.dal.dao.CasssoUserDAO;
import com.h3c.dal.dao.CasssoUserRoleRelationDAO;
import com.h3c.dal.entity.CasssoDeptDO;
import com.h3c.dal.entity.CasssoDeptUserRelationDO;
import com.h3c.dal.entity.CasssoOrganizationUnitDO;
import com.h3c.dal.entity.CasssoRoleDO;
import com.h3c.dal.entity.CasssoUserDO;
import com.h3c.dal.entity.CasssoUserRoleRelationDO;
import com.h3c.dal.entity.query.CasssoDeptQuery;
import com.h3c.dal.entity.query.CasssoDeptUserRelationQuery;
import com.h3c.dal.entity.query.CasssoOrganizationUnitQuery;
import com.h3c.dal.entity.query.CasssoRoleQuery;
import com.h3c.dal.entity.query.CasssoUserQuery;
import com.h3c.dal.entity.query.CasssoUserRoleRelationQuery;
import com.h3c.web.common.BaseResponse;
import com.h3c.web.common.ErrorMsgEnum;
import com.h3c.web.common.constant.AttachConstant;
import com.h3c.web.common.constant.SessionConstant;
import com.h3c.web.common.utils.BeanUtil;
import com.h3c.web.common.utils.ListUtil;
import com.h3c.web.common.utils.MD5Util;
import com.h3c.web.common.utils.UUIDUtil;
import com.h3c.web.common.vo.CasssoDeptVO;
import com.h3c.web.common.vo.CasssoOrganizationUnitVO;
import com.h3c.web.common.vo.CasssoRoleVO;
import com.h3c.web.common.vo.CasssoUserVO;
import com.h3c.web.support.console.OrgSupport;

/**
 * @ClassName: UserRest
 * @Description: 用户api
 * @author: d14287
 * @date: 2017年5月31日 下午3:50:21
 */
@Controller
@RequestMapping("console/user")
public class UserRest {
	public static final Logger logger = LoggerFactory.getLogger(UserRest.class);
	@Autowired
	private CasssoUserDAO casssoUserDAO;
	@Autowired
	private CasssoDeptUserRelationDAO casssoDeptUserRelationDAO;
	@Autowired
	private CasssoDeptDAO casssoDeptDAO;
	@Autowired
	private CasssoUserRoleRelationDAO casssoUserRoleRelationDAO;
	@Autowired
	private CasssoRoleDAO casssoRoleDAO;
	@Autowired
	private CasssoOrganizationUnitDAO casssoOrganizationUnitDAO;
	@Autowired
	private OrgSupport orgSupport;

	/**
	 * 新增用户： 用户 -> 用户角色关联 -> 用户部门关联
	 * @param userVO
	 * @return
	 * @throws Exception
	 */
	@Transactional
	@RequestMapping(value = "/add.ajax", method = RequestMethod.POST)
	public @ResponseBody BaseResponse add(@RequestBody CasssoUserVO userVO) throws Exception {
		CasssoUserDO casssoUserDO = new CasssoUserDO();
		BeanUtil.copyProperties(userVO, casssoUserDO);
		// 重名检查
		if (isLoginIdExist(casssoUserDO.getLoginId())) {
			return BaseResponse.falseOf(ErrorMsgEnum.loginid_already_exist.getMsg());
		}
		casssoUserDO.setUserId(UUIDUtil.generateUUID());
		casssoUserDO.setRegisterTime(new Date());
		casssoUserDO.setStatus(TableConstant.USER_STATUS_ACTIVATED);
		casssoUserDO.setPassword(MD5Util.encryption(casssoUserDO.getPassword()));
		casssoUserDAO.insert(casssoUserDO);
		CasssoUserRoleRelationDO userRoleDO = new CasssoUserRoleRelationDO();
		BeanUtil.copyProperties(userVO, userRoleDO);
		userRoleDO.setUrId(UUIDUtil.generateUUID());
		userRoleDO.setUserId(casssoUserDO.getUserId());
		userRoleDO.setStatus(TableConstant.COMMON_STATUS_NORMAL);
		casssoUserRoleRelationDAO.insert(userRoleDO);
		CasssoDeptUserRelationDO deptUserDO = new CasssoDeptUserRelationDO();
		BeanUtil.copyProperties(userVO, deptUserDO);
		deptUserDO.setUserId(casssoUserDO.getUserId());
		deptUserDO.setDuId(UUIDUtil.generateUUID());
		deptUserDO.setCreateTime(new Date());
		deptUserDO.setStatus(TableConstant.COMMON_STATUS_NORMAL);
		casssoDeptUserRelationDAO.insert(deptUserDO);
		return BaseResponse.trueOf();
	}
	/**
	 * @Desc: 删除用户 ->删除用户部门关联 ->删除用户角色关联
	 * @param userId
	 * @return
	 * @throws Exception
	 * @return: BaseResponse
	 */
	@Transactional
	@RequestMapping(value = "/delete.ajax", method = RequestMethod.POST)
	public @ResponseBody BaseResponse delete(@RequestParam String userId) throws Exception {
		CasssoUserDO userDO = new CasssoUserDO();
		userDO.setStatus(TableConstant.USER_STATUS_DELETE);
		CasssoUserQuery userQuery = new CasssoUserQuery();
		userQuery.createCriteria().andUserIdEqualTo(userId);
		casssoUserDAO.updateByExampleSelective(userDO, userQuery);
		CasssoDeptUserRelationDO deptUserDO = new CasssoDeptUserRelationDO();
		deptUserDO.setStatus(TableConstant.USER_STATUS_DELETE);
		CasssoDeptUserRelationQuery deptUserQuery = new CasssoDeptUserRelationQuery();
		deptUserQuery.createCriteria().andUserIdEqualTo(userId);
		casssoDeptUserRelationDAO.updateByExampleSelective(deptUserDO, deptUserQuery);
		CasssoUserRoleRelationDO userRoleDO = new CasssoUserRoleRelationDO();
		CasssoUserRoleRelationQuery userRoleQuery = new CasssoUserRoleRelationQuery();
		userRoleDO.setStatus(TableConstant.USER_STATUS_DELETE);
		userRoleQuery.createCriteria().andUserIdEqualTo(userId);
		casssoUserRoleRelationDAO.updateByExampleSelective(userRoleDO, userRoleQuery);
		return BaseResponse.trueOf();
	}
	/**
	 * 编辑用户信息： 用户 ->用户角色表 ->用户部门表
	 * @param userVO
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	@RequestMapping(value = "/edit.ajax", method = RequestMethod.POST)
	public @ResponseBody BaseResponse update(@RequestBody CasssoUserVO userVO) throws Exception {
		CasssoUserDO casssoUserDO = new CasssoUserDO();
		userVO.setLoginId(null);
		BeanUtil.copyProperties(userVO, casssoUserDO);
		CasssoUserQuery userQuery = new CasssoUserQuery();
		userQuery.createCriteria().andUserIdEqualTo(userVO.getUserId());
		casssoUserDAO.updateByExampleSelective(casssoUserDO, userQuery);
		CasssoDeptUserRelationDO deptUserDO = new CasssoDeptUserRelationDO();
		deptUserDO.setDeptId(userVO.getDeptId());
		CasssoDeptUserRelationQuery userDeptQuery = new CasssoDeptUserRelationQuery();
		userDeptQuery.createCriteria().andUserIdEqualTo(casssoUserDO.getUserId())
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoDeptUserRelationDO> list = casssoDeptUserRelationDAO.selectByExample(userDeptQuery);
		if (ListUtil.isNotEmpty(list)) {
			casssoDeptUserRelationDAO.updateByExampleSelective(deptUserDO, userDeptQuery);
		} else {
			// 不存在用户部门关系（新增组织时增加的组织管理员）时则新增
			deptUserDO.setCreateTime(new Date());
			deptUserDO.setDuId(UUIDUtil.generateUUID());
			deptUserDO.setUserId(casssoUserDO.getUserId());
			deptUserDO.setStatus(TableConstant.COMMON_STATUS_NORMAL);
			casssoDeptUserRelationDAO.insert(deptUserDO);
		}
		CasssoUserRoleRelationDO userRoleDO = new CasssoUserRoleRelationDO();
		userRoleDO.setRoleId(userVO.getRoleId());
		CasssoUserRoleRelationQuery userRoleQuery = new CasssoUserRoleRelationQuery();
		userRoleQuery.createCriteria().andUserIdEqualTo(userVO.getUserId())
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		casssoUserRoleRelationDAO.updateByExampleSelective(userRoleDO, userRoleQuery);
		return BaseResponse.trueOf();
	}
	@RequestMapping(value = "/personalEdit.ajax", method = RequestMethod.POST)
	public @ResponseBody BaseResponse personalEdit(@RequestBody CasssoUserVO userVO, HttpServletRequest request)
			throws Exception {
		CasssoUserDO casssoUserDO = new CasssoUserDO();
		BeanUtil.copyProperties(userVO, casssoUserDO);
		String userId = (String) request.getSession().getAttribute(SessionConstant.USER_ID);
		casssoUserDO.setUserId(userId);
		if (StringUtils.isNotBlank(casssoUserDO.getPassword())) {
			casssoUserDO.setPassword(MD5Util.encryption(casssoUserDO.getPassword()));
		}
		casssoUserDAO.updateByPrimaryKeySelective(casssoUserDO);
		return BaseResponse.trueOf();
	}
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/query.ajax", method = RequestMethod.GET)
	public @ResponseBody BaseResponse query(@RequestParam(value = "userId", required = false) String userId,
			@RequestParam(value = "attach", required = false) String attach, HttpServletRequest request)
			throws Exception {
		userId = StringUtils.isBlank(userId) ? (String) request.getSession().getAttribute(SessionConstant.USER_ID)
				: userId;
		CasssoUserQuery userQuery = new CasssoUserQuery();
		userQuery.createCriteria().andUserIdEqualTo(userId).andStatusNotEqualTo(TableConstant.COMMON_STATUS_DELETE);
		List<CasssoUserDO> casssoUserDOList = casssoUserDAO.selectByExample(userQuery);
		if (ListUtil.isEmpty(casssoUserDOList)) {
			return BaseResponse.trueOf();
		}
		CasssoUserVO casssoUserVO = new CasssoUserVO();
		casssoUserVO.setName(casssoUserDOList.get(0).getName());
		casssoUserVO.setLoginId(casssoUserDOList.get(0).getLoginId());
		casssoUserVO.setIdNumber(casssoUserDOList.get(0).getIdNumber());
		casssoUserVO.setEmail(casssoUserDOList.get(0).getEmail());
		casssoUserVO.setMobilephone(casssoUserDOList.get(0).getMobilephone());
		if (StringUtils.contains(attach, AttachConstant.DEPT)) {
			queryDept(casssoUserVO);
		}
		if (StringUtils.contains(attach, AttachConstant.ROLE))
			queryRole(casssoUserVO);
		return BaseResponse.trueOf(casssoUserVO);
	}
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/queryImg.ajax", method = RequestMethod.GET)
	public void queryImg(@RequestParam(value = "userId", required = false) String userId, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		userId = StringUtils.isBlank(userId) ? (String) request.getSession().getAttribute(SessionConstant.USER_ID)
				: userId;
		CasssoUserQuery userQuery = new CasssoUserQuery();
		userQuery.createCriteria().andUserIdEqualTo(userId).andStatusNotEqualTo(TableConstant.COMMON_STATUS_DELETE);
		List<CasssoUserDO> casssoUserDOList = casssoUserDAO.selectByExample(userQuery);
		if (ListUtil.isEmpty(casssoUserDOList)) {
			return;
		}
		byte[] imgbyte = casssoUserDOList.get(0).getPhoto();
		response.setHeader("content-type", "image/jpeg");
		response.getOutputStream().write(imgbyte);
	}
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/pageQuery.ajax", method = RequestMethod.GET)
	public @ResponseBody BaseResponse queryDetpUser(@RequestParam(value = "pageIndex") Integer pageIndex,
			HttpServletRequest request) throws Exception {
		Pair<CasssoUserQuery, CasssoUserQuery.Criteria> pair = orgSupport.generateUserQuery(request);
		pair.getRight().andStatusNotEqualTo(TableConstant.USER_STATUS_DELETE);
		pair.getLeft().setPageSize(5);
		pair.getLeft().setPageIndex(pageIndex);
		List<CasssoUserDO> userList = casssoUserDAO.pageSelectByExample(pair.getLeft());
		List<CasssoUserVO> userListVO = ListUtil.copyList(userList, CasssoUserVO.class);
		userListVO.forEach(vo -> {
			try {
				queryDept(vo);
				queryDeptIds(vo);
				queryRole(vo);
			} catch (Exception e) {
				logger.error("queryDetpUser happened error", e);
			}
		});
		Map<String, Object> data = Maps.newHashMap();
		data.put("total",pair.getLeft().getCount());
		data.put("totalPage",pair.getLeft().getPageCount());
		data.put("pageIndex",pair.getLeft().getPageIndex());
		data.put("userList", userListVO);
		data.put("pageSize", pair.getLeft().getPageSize());
		return BaseResponse.trueOf(data);
	}
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/fuzzyQuery.ajax", method = RequestMethod.GET)
	public @ResponseBody BaseResponse fuzzyQuery(@RequestParam(value = "key") String key) throws Exception {
		CasssoUserQuery userQuery = new CasssoUserQuery();
		userQuery.createCriteria().andNameLike("%" + key + "%");
		userQuery.or(userQuery.createCriteria().andLoginIdLike("%" + key + "%"));
		List<CasssoUserDO> userListDO = casssoUserDAO.selectByExample(userQuery);
		List<CasssoUserVO> userListVO = ListUtil.copyList(userListDO, CasssoUserVO.class);
		Map<String, Object> data = Maps.newHashMap();
		if (userListVO == null) {
			data.put("userList", Lists.newArrayList());
			return BaseResponse.trueOf(data);
		}
		userListVO.forEach(vo -> {
			try {
				queryDept(vo);
				queryDeptIds(vo);
				queryRole(vo);
			} catch (Exception e) {
				logger.error("fuzzyQuery happened error", e);
			}
		});
		data.put("userList", userListVO);
		return BaseResponse.trueOf(data);
	}
	// 查询部门
	@SuppressWarnings("unchecked")
	public void queryDept(CasssoUserVO userVO) throws Exception {
		CasssoDeptUserRelationQuery deptUserRelationQuery = new CasssoDeptUserRelationQuery();
		deptUserRelationQuery.createCriteria().andUserIdEqualTo(userVO.getUserId())
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoDeptUserRelationDO> relationList = casssoDeptUserRelationDAO.selectByExample(deptUserRelationQuery);
		if (ListUtil.isNotEmpty(relationList)) {
			CasssoDeptQuery deptQuery = new CasssoDeptQuery();
			deptQuery.createCriteria().andDeptIdEqualTo(relationList.get(0).getDeptId())
					.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
			List<CasssoDeptDO> deptList = casssoDeptDAO.selectByExample(deptQuery);
			if (ListUtil.isNotEmpty(deptList)) {
				CasssoDeptVO depVO = new CasssoDeptVO();
				BeanUtil.copyProperties(deptList.get(0), depVO);
				userVO.setCasssoDeptVO(depVO);
			}
		}
		CasssoOrganizationUnitQuery orgQuery = new CasssoOrganizationUnitQuery();
		orgQuery.createCriteria().andOuIdEqualTo(userVO.getOuId())
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoOrganizationUnitDO> orgList = casssoOrganizationUnitDAO.selectByExample(orgQuery);
		if (ListUtil.isNotEmpty(orgList)) {
			CasssoOrganizationUnitVO orgVO = new CasssoOrganizationUnitVO();
			BeanUtil.copyProperties(orgList.get(0), orgVO);
			userVO.setCasssoOrganizationUnitVO(orgVO);
		}
	}
	public void queryDeptIds(CasssoUserVO userVO) throws Exception {
		CasssoDeptDO deptDO = new CasssoDeptDO();
		if (userVO.getCasssoDeptVO() == null) {
			return;
		}
		BeanUtil.copyProperties(userVO.getCasssoDeptVO(), deptDO);
		List<CasssoDeptDO> deptList = Lists.newArrayList();
		deptList.add(deptDO);
		queryParentDept(deptList, 0);
		List<String> deptIds = Lists.newArrayList();
		deptList.forEach(dept -> {
			deptIds.add(dept.getDeptId());
		});
		Collections.reverse(deptIds);
		userVO.setDeptIds(deptIds);
	}
	@SuppressWarnings("unchecked")
	public void queryParentDept(List<CasssoDeptDO> deptDos, int flag) throws Exception {
		CasssoDeptQuery deptQuery = new CasssoDeptQuery();
		CasssoDeptDO currentDO = deptDos.get(deptDos.size() - 1);
		if (StringUtils.isEmpty(currentDO.getParentId())) {
			return;
		}
		deptQuery.createCriteria().andParentIdEqualTo(currentDO.getParentId())
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoDeptDO> deptList = casssoDeptDAO.selectByExample(deptQuery);
		if (ListUtil.isNotEmpty(deptList)) {
			deptDos.add(deptList.get(0));
		}
		// 防止数据有误，出现死循环
		if (flag++ == 10) {
			return;
		}
		queryParentDept(deptDos, flag);
	}
	// 查询角色
	@SuppressWarnings("unchecked")
	public void queryRole(CasssoUserVO userVO) throws Exception {
		CasssoUserRoleRelationQuery userRoleRelationQuery = new CasssoUserRoleRelationQuery();
		userRoleRelationQuery.createCriteria().andUserIdEqualTo(userVO.getUserId())
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoUserRoleRelationDO> relationList = casssoUserRoleRelationDAO.selectByExample(userRoleRelationQuery);
		if (ListUtil.isEmpty(relationList))
			return;
		CasssoRoleQuery roleQuery = new CasssoRoleQuery();
		roleQuery.createCriteria().andRoleIdEqualTo(relationList.get(0).getRoleId())
				.andStatusEqualTo(TableConstant.COMMON_STATUS_NORMAL);
		List<CasssoRoleDO> roleList = casssoRoleDAO.selectByExample(roleQuery);
		if (ListUtil.isEmpty(roleList))
			return;
		CasssoRoleVO casssoRoleVO = new CasssoRoleVO();
		BeanUtil.copyProperties(roleList.get(0), casssoRoleVO);
		userVO.setCasssoRoleVO(casssoRoleVO);
	}
	/**
	 * 重名检查
	 * @param loginId
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public boolean isLoginIdExist(String loginId) throws SQLException {
		CasssoUserQuery userQuery = new CasssoUserQuery();
		userQuery.createCriteria().andLoginIdEqualTo(loginId);
		List<CasssoUserDO> userList = casssoUserDAO.selectByExample(userQuery);
		if (ListUtil.isNotEmpty(userList)) {
			return true;
		}
		return false;
	}
}
